package com.atguigu.gmall.order.controller;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.execption.GmallException;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Ordering;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/order")
@SuppressWarnings("all")
public class OrderApiController {




    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;



    /**
     * api/order/inner/seckill/submitOrder
     * 秒杀接口-提交订单
     * @param orderInfo
     * @return
     */
    @PostMapping("/inner/seckill/submitOrder")
    public Long submitOrder(@RequestBody OrderInfo orderInfo){

        //保存订单
        Long orderId = orderInfoService.submitOrder(orderInfo);
        return orderId;

    }


    /**
     * http://localhost:8204/api/order/orderSplit
     * 拆单
     * @param request
     * @return
     */
    @PostMapping("/orderSplit")
    public String orderSplit(HttpServletRequest request){
        //获取订单
        String orderId = request.getParameter("orderId");
        //获取拆单规则 1- 21 22 2-29 30
        //[{"wareId":"1","skuIds":["2","10"]},{"wareId":"2","skuIds":["3"]}]
        String wareSkuMap = request.getParameter("wareSkuMap");

        //调用拆单业务
        List<OrderInfo> orderInfoList=orderInfoService.orderSplit(orderId,wareSkuMap);

        List< Map<String, Object>> orderStrList = orderInfoList.stream().map(orderInfo -> {

            Map<String, Object> stringObjectMap = orderInfoService.getStringObjectMap(orderInfo);

            return stringObjectMap;
        }).collect(Collectors.toList());
        String string = JSON.toJSONString(orderStrList);

        return string;
    }


    /**
     * /api/order/inner/getOrderInfo/{orderId}
     * 根据id查询orderInfo
     * @param orderId
     * @return
     */
    @GetMapping("/inner/getOrderInfo/{orderId}")
    public Result<OrderInfo> getOrderInfo(@PathVariable Long orderId){

        return Result.ok(orderInfoService.getById(orderId));

    }

    /**
     * 我的订单
     * /api/order/auth/{page}/{limit}
     * @param page
     * @param limit
     * @return
     */
    @GetMapping("/auth/{page}/{limit}")
    public Result getOrderByUserId(@PathVariable Long page,
                                   @PathVariable Long limit,
                                   HttpServletRequest request){
        //封装分页条件
        Page<OrderInfo> orderInfoPage=new Page<>(page,limit);
        //获取用户id
        String userId = AuthContextHolder.getUserId(request);

        IPage<OrderInfo> infoIPage= orderInfoService.getOrderByUserId(orderInfoPage,userId);


        return Result.ok(infoIPage);
    }


    /**
     * 提交订单
     * api/order/auth/submitOrder
     * @return
     */
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo,HttpServletRequest request){

        //获取用户id
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.valueOf(userId));

        //获取页面流水号
        String tradeNo = request.getParameter("tradeNo");

        //校验流水号
        boolean result = orderInfoService.checkTradeNo(userId, tradeNo);
        if(!result){

            return Result.fail().message("订单不可重复提交！！");
        }

        //定义集合收集异常信息
        List<String> errorList=new ArrayList<>();
        //定义集合接收异步对象
        List<CompletableFuture> futureList=new ArrayList<>();

        //校验库存--有库存
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        //遍历处理
        for (OrderDetail orderDetail : orderDetailList) {
            //校验库存
            CompletableFuture<Void> stockFuture = CompletableFuture.runAsync(() -> {

                boolean flag = orderInfoService.checkStock(orderDetail.getSkuId(), orderDetail.getSkuNum());
                //判断
                if (!flag) {

                    errorList.add(orderDetail.getSkuId() + ":" + orderDetail.getSkuName() + ":库存不足！");
                }

            }, threadPoolExecutor);

            futureList.add(stockFuture);



            //校验价格
            CompletableFuture<Void> checkPriceFuture = CompletableFuture.runAsync(() -> {
                BigDecimal skuPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
                //比较
                if (orderDetail.getOrderPrice().compareTo(skuPrice) != 0) {
                    //更新最新商品价格
                    List<CartInfo> cartCheckedList = cartFeignClient.getCartCheckedList(userId);

                    //更新购物车redis
                    cartCheckedList.forEach(cartInfo -> {
                        redisTemplate.opsForHash().put(
                                RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX,
                                cartInfo.getSkuId().toString(),
                                cartInfo
                        );

                    });


                    errorList.add(orderDetail.getSkuId() + ":" + orderDetail.getSkuName() + ":价格有变动！");


                }
            }, threadPoolExecutor);

            futureList.add(checkPriceFuture);


        }

        //编排处理
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();

        //判断
        if(errorList.size()>0){


            return Result.fail().message(StringUtils.join(errorList,","));
        }



        //调用service
        Long orderId=  orderInfoService.submitOrder(orderInfo);

        //删除流水号
        orderInfoService.deleteTradeNo(userId);

        return Result.ok(orderId);
    }


    /**
     * 去结算
     * api/order/auth/trade
     * @return
     */
    @GetMapping("/auth/trade")
    public Result trade(HttpServletRequest request){

        //定义map存储数据
        Map<String,Object> resultMap=new HashMap<>();
        //获取userId
        String userId = AuthContextHolder.getUserId(request);
        //判断
        if(StringUtils.isEmpty(userId)){
            throw new GmallException( ResultCodeEnum.ILLEGAL_REQUEST);
        }
        //获取用户地址列表
        List<UserAddress> userAddressListByUserId = userFeignClient.findUserAddressListByUserId(Long.valueOf(userId));

        //获取用户选中的送货清单
        List<CartInfo> cartCheckedList = cartFeignClient.getCartCheckedList(userId);
        //转换数据
        List<OrderDetail> orderDetailList = cartCheckedList.stream().map(cartInfo -> {
            //创建订单明细对象
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setSkuId(cartInfo.getSkuId());
            orderDetail.setSkuName(cartInfo.getSkuName());
            orderDetail.setImgUrl(cartInfo.getImgUrl());
            orderDetail.setOrderPrice(cartInfo.getSkuPrice());
            orderDetail.setSkuNum(cartInfo.getSkuNum());
            return orderDetail;
        }).collect(Collectors.toList());

        //计算数据量
        int totalNum = orderDetailList.size();
        //计算总金额
        OrderInfo orderInfo=new OrderInfo();
        //设置订单明细集合
        orderInfo.setOrderDetailList(orderDetailList);
        //调用计算方法
        orderInfo.sumTotalAmount();
        //获取总金额
        BigDecimal totalAmount = orderInfo.getTotalAmount();

        resultMap.put("detailArrayList",orderDetailList);
        resultMap.put("userAddressList",userAddressListByUserId);
        resultMap.put("totalAmount",totalAmount);
        resultMap.put("totalNum",totalNum);

        //生成流水号
        String tradeNo = orderInfoService.getTradeNo(userId);
        resultMap.put("tradeNo",tradeNo);

        return Result.ok(resultMap);
    }
}
